import axios from 'axios';
import {
  history
} from '../index'
import {
  Modal
} from 'antd'
import {
  message
} from 'antd'
import {
  login
} from './Urls'
import {
  CookieUtil
} from '@/Utils/index'
const instance = axios.create({
  withCredentials: true, // 开启这个配置项才可以接受服务器端发送的cookies
  baseURL: '/api'
})

// 是否已拦截
let isIntercepting = false;
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  // 如果是刷新token的请求就直接返回数据
  // if (config.url === refreshToken) {
  //   return config;
  // }
  // 如果已经处于拦截状态则不在接受请求
  if (isIntercepting) return Promise.reject()

  //判断token过期没
  // JSON.parse(CookieUtil.get("userMessage")).expires > new Date().valueOf() true就是没过期

  // 在发送请求之前做些什么
  //如果是登录接口，不需要token
  if (config.url === login) {
    config.headers.Authorization = '';
  }
  if (config.url === login || JSON.parse(CookieUtil.get("userMessage"))?.expireAt) {
    isIntercepting = false
    return config;
  } else {
    Modal.confirm({
      title: "提示",
      content: "登陆状态已过期请重新登陆",
      onOk (close) {
        history.push('/')
        close()
        isIntercepting = false
      },
      onCancel (close) {
        close();
        isIntercepting = false
      }
    })
    CookieUtil.unset('userMessage')
  }
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

//增加get
const methodList = ['post', 'put', 'patch', 'get']

/**
 *
 * @param {传入的参数}
 * 用于将参数从对象转化成qs
 */
const stringifyData = (data) => {
  let res = []
  Object.keys(data).forEach((key) => {
    if (data[key] === null || data[key] === undefined) { } else {
      res.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
    }
  })
  return res.join('&')
}


const toFormData = (data) => {
  var formData = new FormData();
  Object.keys(data).forEach(key => {
    let dataKey = data[key];
    if (Array.isArray(dataKey)) { // 发送数组
      for (let i = 0; i < dataKey.length; i++) {
        formData.append(`${key}`, dataKey[i]);
      }
    } else {
      formData.append(key, dataKey);
    }
  })
  return formData;
}


/**
 * [_fetch 用于http请求]
 * @param  {[type]} option [传入配置参数，用法类似 $.ajax]
 * @return {[type]}        [返回promise对象，用then方法获取返回的数据]
 *
 */
const _fetch = (option) => {
  // 默认请求头
  var headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    // 'Cookie': document.cookie
  };

  // 如果是登录就不带token
  if (option.url !== login && JSON.parse(CookieUtil.get('userMessage'))) {
    headers.Authorization = JSON.parse(CookieUtil.get('userMessage')).token // 获取请求头
  }

  // if (!(option.headers && option.headers.Authorization)) {
  //   if (JSON.parse(CookieUtil.get('userMessage'))) {
  //     headers.Authorization = JSON.parse(CookieUtil.get('userMessage')).token // 获取请求头
  //   }
  // }
  if (!option.url) {

    // console.error('使用_fetch时请先填入url');
    return
  }

  let progressListen
  if (option.file) {
    progressListen = progressEvent => {
      let percent = (progressEvent.loaded / progressEvent.total * 100 | 0)
      if (percent !== 100) {
        option.file.onProgress({
          percent
        })
      } else {
        option.file.onSuccess()
      }
    }
  } else {
    progressListen = null;
  }

  let requestPromise
  methodList.forEach((method) => {
    if (option.type && option.type.toLowerCase() === method) {
      var finalData = {}
      // 如果_fetch请求有带请求头,则覆盖原来的默认请求头
      if (option.headers) {
        // newHeader =
        headers = Object.assign(headers, option.headers)
        // 如果请求是application/json,则把对象转为json字符串
        if (headers['Content-Type'] === 'application/json') {
          finalData = option.data ? JSON.stringify(option.data) : {}
        }
        //如果请求是multipart/form-data，则把json对象转换为formData对象,当然也可以直接发
        if (headers['Content-Type'] === 'multipart/form-data') {
          if (option.data) {
            if (Object.prototype.toString.call(option.data) === '[object FormData]') {
              finalData = option.data
            } else {
              finalData = toFormData(option.data);
            }
          }
        }

        if (headers['Content-Type'] === 'application/x-www-form-urlencoded') {
          finalData = option.data ? stringifyData(option.data) : {}
        }

      } else if (option.isJson) {
        // 如果有isJson：true这个配置则conten-type为json类型
        headers = Object.assign(headers, {
          'Content-Type': 'application/json'
        })
        finalData = option.data ? JSON.stringify(option.data) : {}
      } else if (option.type === 'get') {
        headers = {
          'Authorization': headers.Authorization
        }
      } else {
        headers = Object.assign(headers, {
          'Content-Type': 'application/x-www-form-urlencoded'
        })
        finalData = option.data ? stringifyData(option.data) : {}
      }

      requestPromise = instance.request({
        headers: headers,
        url: option.url,
        method: option.type.toLowerCase(),
        data: finalData,
        responseType: option.responseType ? option.responseType : 'json',
        // 如果有上传文件，监听进度
        onUploadProgress: progressListen
      })

    }
  })
  //除了那三种方法之外的方法
  if (!requestPromise) {
    var finalData = option.data
    let headers = {}
    if (option.headers && option.headers.Authorization) {
      headers.Authorization = decodeURI(option.headers.Authorization)
    } else if (JSON.parse(CookieUtil.get('userMessage'))) {
      headers.Authorization = JSON.parse(CookieUtil.get('userMessage')).token // 获取请求头
    }
    let type = option.type || 'get'
    type = type.toLowerCase()
    requestPromise = instance.request({
      headers,
      url: option.url,
      method: type,
      params: finalData || option.params || {},
      responseType: option.responseType ? option.responseType : 'json'
    })
  }
  return requestPromise.then(
    (res) => {
      if (res.data.success) {
        return res
      } else {
        if (res.data.message) {
          message.error(res.data.message);
        }
        return res
      }
    }
  )
}

export default _fetch